<?php

/**
 * Description of XDS_DataSource
 *
 * @author prometheus
 */
class XDS_DataSource extends x10_GeneralClass
{
	public $xName = 'Adatforrás: ';

	public $name = '';

	public $resultProvider = 'XDS_DataSource_ResultProvider';

	/**
	 * @var XQL_QuerySet
	 */
	protected $queryset;

	/**
	 * @var XDS_RecordSet
	 */
	protected $recordset;

	/**
	 * @var XQL_Query
	 */
	protected $lastQuery;

	/**
	 * @var XDS_Pager
	 */
	protected $pager;

	public function __construct(x10_Config $config)
	{
		parent::__construct($config);

		$this->name = $this->config->getConfigKey('name');
		$this->xName .= $this->name;

		$rp = $this->config->getConfigKey('resultProvider');
		if (!is_null($rp)) $this->resultProvider = $rp;

		$pg = $this->config->getConfigKey('pager');
		if (!is_null($pg))
		{
			$class = $pg->className;
			$this->pager = new $class(new x10_Config((array)$pg->config));
		}

		$qs = $this->config->getConfigKey('queryset');
		if (!is_null($qs))
		{
			if (!isset($qs->preset))
			{
				$this->queryset = new $qs->className();
			}
			else
			{
				$this->queryset = new $qs->className($qs->preset);
			}
		}
	}

	public function setPagerOffset($offset)
	{
		$this->pager->offset = $offset;
	}

	protected function createRecordSet()
	{
		$rs = $this->config->getConfigKey('recordset');
		if (!is_null($rs))
		{
			if (is_string($rs->config))
			{
				$rsURL = new x10_Util_URL($rs->config);
				if (!$rsURL->hasValidScheme())
				{
					$rsURL->part_scheme = 'file';
					$rsURL->part_path = API_ConfigManager::$systemPath.$rsURL->part_path;
				}
				$rs->config = (string)$rsURL;
				unset($rsURL);
			}
			$this->recordset = new $rs->className(new x10_Config($rs->config));
		}
	}

	/**
	 * Visszaadja a kezelt rekordhalmazt.
	 * @return XDS_RecordSet
	 */
	public function getRecordSet()
	{
		return $this->recordset;
	}

	/**
	 * Egyszerű rekordhalmazt importál az adatforrásba, egyben visszatér ezen
	 * rekordokkal a megfelelő visszatérés-szolgáltató segítségével.
	 * 
	 * @param Array $records
	 * @return XDS_DataSource_ResultProvider
	 */
	public function import($records)
	{
		if (is_array($records) and isset($records[0]) and is_array($records[0]))
		{
			$this->createRecordSet();

			$this->recordset->count = count($result);
			$recordsIter = $records;
			if (!is_null($this->pager)) $recordsIter = $this->pager->getIterator($records);

			$this->recordset->open();
			foreach ($recordsIter as $rid=>$data)
			{
				$record = $this->recordset->createRecordProvider();
				$record->set($this->onRecordSet($data));
				$this->recordset[] = $record;
			}
			$this->recordset->close();
			unset($recordsIter);

			$rp = new $this->resultProvider(new x10_Config(array('recordset'=>$this->recordset)));
			return $rp;
		}
		else
		{
			return $records;
		}
	}

	public function save()
	{
		$added = $this->recordset->getAddedRecords();
		$modified = $this->recordset->getModifiedRecords();
		$removed = $this->recordset->getRemovedRecords();

		foreach ($added as $prov)
		{
			if (is_object($prov)) $this->execute('add', array((array)$prov->get()));
		}
		unset($added);

		foreach ($modified as $prov)
		{
			if (is_object($prov)) $this->execute('modify', array((array)$prov->get(), $prov->getPKValues()));
		}
		unset($modified);

		foreach ($removed as $prov)
		{
			if (is_object($prov)) $this->execute('remove', array($prov->getPKValues()));
		}
		unset($removed);
	}

	/**
	 * @param String $queryName
	 * @param Array $args
	 * @return XDS_DataSource_ResultProvider
	 */
	public function execute($queryName, $args=array())
	{
		unset($this->recordset);
		$this->recordset = NULL;
		
		$this->lastQuery = $this->$queryName;
		$result = $this->lastQuery->execute($args);

		$this->createRecordSet();

		$this->recordset->count = count($result);

		// ha adatsorok tértek vissza.
		if (is_array($result) and isset($result[0]) and is_array($result[0]))
		{
			$resultIter = $result;
			if (!is_null($this->pager)) $resultIter = $this->pager->getIterator($result);
			
			$this->recordset->open();
			foreach ($resultIter as $rid=>$data)
			{
				$record = $this->recordset->createRecordProvider();
				$record->set($this->onRecordSet($data));
				$record->setRecordSet($this->recordset);
				$record->setRecordIdx(count($this));
				$this->recordset[] = $record;
				unset($result[$rid]); // Spórolás a memóriával.
			}
			$this->recordset->close();
			unset($result, $resultIter);

			$rp = new $this->resultProvider(new x10_Config(array('recordset'=>$this->recordset)));
			return $rp;
		}
		else
		{
			return $result;
		}
	}

	/**
	 * Akkor kerül meghívásra, amikor az adatforrás feltöltődik rekordokkal.
	 * Az adatforrásba az adott rekord úgy fog bekerülni, ahogyan ez a metódus
	 * visszatér.
	 *
	 * @param Array $data
	 * @return Array
	 */
	protected function onRecordSet($data)
	{
		return $data;
	}

	/**
	 * @param String $resultProvider
	 * @return XDS_DataSource_ResultProvider
	 */
	public function getResultAs($resultProvider)
	{
		$result = NULL;
		if (isset($this->recordset))
		{
			$rp = new $resultProvider(new x10_Config(array('recordset'=>$this->recordset)));
			$result = $rp;
		}
		return $result;
	}

	/**
	 * @param String $resultProvider
	 * @return XDS_DataSource_ResultProvider
	 */
	public function getResult()
	{
		$result = new $this->resultProvider(new x10_Config(array('recordset'=>$this->recordset)));
		return $result;
	}

	public function __get($name)
	{
		return $this->queryset->$name;
	}
}

?>